ref count nodes the proper way, (gtk_tree_model_sort_ref_node),
authorKristian Rietveld <kris@imendio.com>
Wed, 27 Sep 2006 12:08:12 +0000 (12:08 +0000)
committerKristian Rietveld <kristian@src.gnome.org>
Wed, 27 Sep 2006 12:08:12 +0000 (12:08 +0000)
2006-09-26  Kristian Rietveld  <kris@imendio.com>

* gtk/gtktreemodelsort.c (gtk_tree_model_sort_row_changed),
(gtk_tree_model_sort_sort_level): ref count nodes the proper way,
(gtk_tree_model_sort_ref_node), (gtk_tree_model_sort_real_unref_node),
(gtk_tree_model_sort_free_level): bring zero ref count loops in
sync,
(gtk_tree_model_sort_free_level): free child levels before
decreasing the zero ref count of the current level,
(gtk_tree_model_sort_clear_cache): only clear cache if zero_ref_count
is > 0.

ChangeLog
gtk/gtktreemodelsort.c

index 59114edd311438b0b76ae7ab374fd5c14b045dca..3b00f9d471d567aec3b2c80eb5efa1cc2221a851 100644 (file)
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,15 @@
+2006-09-26  Kristian Rietveld  <kris@imendio.com>
+
+       * gtk/gtktreemodelsort.c (gtk_tree_model_sort_row_changed),
+       (gtk_tree_model_sort_sort_level): ref count nodes the proper way,
+       (gtk_tree_model_sort_ref_node), (gtk_tree_model_sort_real_unref_node),
+       (gtk_tree_model_sort_free_level): bring zero ref count loops in
+       sync,
+       (gtk_tree_model_sort_free_level): free child levels before
+       decreasing the zero ref count of the current level,
+       (gtk_tree_model_sort_clear_cache): only clear cache if zero_ref_count
+       is > 0.
+
 2006-09-25  Matthias Clasen  <mclasen@redhat.com>
 
        * demos/gtk-demo/*.c:
index b557fe3f166ef543d346e38b11f025e30a2026b9..cf0094486570e26b380f033a243eb77f70745db3 100644 (file)
@@ -441,12 +441,11 @@ gtk_tree_model_sort_row_changed (GtkTreeModel *s_model,
     }
 
   gtk_tree_model_get_iter (GTK_TREE_MODEL (data), &iter, path);
+  gtk_tree_model_sort_ref_node (GTK_TREE_MODEL (data), &iter);
 
   level = iter.user_data;
   elt = iter.user_data2;
 
-  level->ref_count++;
-
   if (level->array->len < 2 ||
       (tree_model_sort->sort_column_id == GTK_TREE_SORTABLE_DEFAULT_SORT_COLUMN_ID &&
        tree_model_sort->default_sort_func == NO_SORT_FUNC))
@@ -455,11 +454,10 @@ gtk_tree_model_sort_row_changed (GtkTreeModel *s_model,
        gtk_tree_path_free (start_s_path);
 
       gtk_tree_model_row_changed (GTK_TREE_MODEL (data), path, &iter);
+      gtk_tree_model_sort_unref_node (GTK_TREE_MODEL (data), &iter);
 
       gtk_tree_path_free (path);
 
-      level->ref_count--;
-
       return;
     }
   
@@ -565,11 +563,10 @@ gtk_tree_model_sort_row_changed (GtkTreeModel *s_model,
       g_free (new_order);
     }
 
-  level->ref_count--;
-
   /* emit row_changed signal (at new location) */
   gtk_tree_model_get_iter (GTK_TREE_MODEL (data), &iter, path);
   gtk_tree_model_row_changed (GTK_TREE_MODEL (data), path, &iter);
+  gtk_tree_model_sort_unref_node (GTK_TREE_MODEL (data), &iter);
 
   gtk_tree_path_free (path);
   if (free_s_path)
@@ -1195,20 +1192,16 @@ gtk_tree_model_sort_ref_node (GtkTreeModel *tree_model,
       SortLevel *parent_level = level->parent_level;
       SortElt *parent_elt = level->parent_elt;
       /* We were at zero -- time to decrement the zero_ref_count val */
-      do
+      while (parent_level)
        {
-         if (parent_elt)
-           parent_elt->zero_ref_count--;
-         else
-           tree_model_sort->zero_ref_count--;
+         parent_elt->zero_ref_count--;
 
-         if (parent_level)
-           {
-             parent_elt = parent_level->parent_elt;
-             parent_level = parent_level->parent_level;
-           }
+         parent_elt = parent_level->parent_elt;
+         parent_level = parent_level->parent_level;
        }
-      while (parent_level);
+
+      if (tree_model_sort->root != level)
+       tree_model_sort->zero_ref_count--;
     }
 }
 
@@ -1253,7 +1246,9 @@ gtk_tree_model_sort_real_unref_node (GtkTreeModel *tree_model,
          parent_elt = parent_level->parent_elt;
          parent_level = parent_level->parent_level;
        }
-      tree_model_sort->zero_ref_count++;
+
+      if (tree_model_sort->root != level)
+       tree_model_sort->zero_ref_count++;
     }
 }
 
@@ -1504,6 +1499,7 @@ gtk_tree_model_sort_sort_level (GtkTreeModelSort *tree_model_sort,
                                gboolean          emit_reordered)
 {
   gint i;
+  gint ref_offset;
   GArray *sort_array;
   GArray *new_array;
   gint *new_order;
@@ -1518,7 +1514,12 @@ gtk_tree_model_sort_sort_level (GtkTreeModelSort *tree_model_sort,
   if (level->array->len < 1 && !((SortElt *)level->array->data)->children)
     return;
 
-  level->ref_count++;
+  iter.stamp = tree_model_sort->stamp;
+  iter.user_data = level;
+  iter.user_data2 = &g_array_index (level->array, SortElt, 0);
+
+  gtk_tree_model_sort_ref_node (GTK_TREE_MODEL (tree_model_sort), &iter);
+  ref_offset = g_array_index (level->array, SortElt, 0).offset;
 
   /* Set up data */
   data.tree_model_sort = tree_model_sort;
@@ -1642,7 +1643,22 @@ gtk_tree_model_sort_sort_level (GtkTreeModelSort *tree_model_sort,
 
   g_free (new_order);
 
-  level->ref_count--;
+  /* get the iter we referenced at the beginning of this function and
+   * unref it again
+   */
+  iter.stamp = tree_model_sort->stamp;
+  iter.user_data = level;
+
+  for (i = 0; i < level->array->len; i++)
+    {
+      if (g_array_index (level->array, SortElt, i).offset == ref_offset)
+        {
+         iter.user_data2 = &g_array_index (level->array, SortElt, i);
+         break;
+       }
+    }
+
+  gtk_tree_model_sort_unref_node (GTK_TREE_MODEL (tree_model_sort), &iter);
 }
 
 static void
@@ -2232,32 +2248,28 @@ gtk_tree_model_sort_free_level (GtkTreeModelSort *tree_model_sort,
 
   g_assert (sort_level);
 
+  for (i = 0; i < sort_level->array->len; i++)
+    {
+      if (g_array_index (sort_level->array, SortElt, i).children)
+       gtk_tree_model_sort_free_level (tree_model_sort,
+                                       SORT_LEVEL (g_array_index (sort_level->array, SortElt, i).children));
+    }
+
   if (sort_level->ref_count == 0)
     {
       SortLevel *parent_level = sort_level->parent_level;
       SortElt *parent_elt = sort_level->parent_elt;
 
-      do
+      while (parent_level)
        {
-         if (parent_elt)
-           parent_elt->zero_ref_count--;
-         else
-           tree_model_sort->zero_ref_count--;
+         parent_elt->zero_ref_count--;
 
-         if (parent_level)
-           {
-             parent_elt = parent_level->parent_elt;
-             parent_level = parent_level->parent_level;
-           }
+         parent_elt = parent_level->parent_elt;
+         parent_level = parent_level->parent_level;
        }
-      while (parent_level);
-    }
 
-  for (i = 0; i < sort_level->array->len; i++)
-    {
-      if (g_array_index (sort_level->array, SortElt, i).children)
-       gtk_tree_model_sort_free_level (tree_model_sort, 
-                                       SORT_LEVEL(g_array_index (sort_level->array, SortElt, i).children));
+      if (sort_level != tree_model_sort->root)
+       tree_model_sort->zero_ref_count--;
     }
 
   if (sort_level->parent_elt)
@@ -2349,7 +2361,7 @@ gtk_tree_model_sort_clear_cache (GtkTreeModelSort *tree_model_sort)
 {
   g_return_if_fail (GTK_IS_TREE_MODEL_SORT (tree_model_sort));
 
-  if (tree_model_sort->zero_ref_count)
+  if (tree_model_sort->zero_ref_count > 0)
     gtk_tree_model_sort_clear_cache_helper (tree_model_sort, (SortLevel *)tree_model_sort->root);
 }